/**
 * 文件管理路由
 * File Management Routes
 */

const express = require('express');
const { query, body, validationResult } = require('express-validator');
const path = require('path');
const fs = require('fs').promises;
const router = express.Router();

const File = require('../database/models/File');
const fileUploadService = require('../services/FileUploadService');
const logger = require('../utils/logger');

/**
 * 获取文件列表
 * GET /api/files
 */
router.get('/',
  [
    query('page')
      .optional()
      .isInt({ min: 1 })
      .withMessage('页码必须是正整数 / Page must be a positive integer'),
    query('pageSize')
      .optional()
      .isInt({ min: 1, max: 100 })
      .withMessage('每页数量必须在1-100之间 / Page size must be between 1-100'),
    query('folderPath')
      .optional()
      .isLength({ max: 500 })
      .withMessage('文件夹路径不能超过500字符 / Folder path cannot exceed 500 characters'),
    query('fileType')
      .optional()
      .isIn(['image', 'video', 'audio', 'document', 'other'])
      .withMessage('文件类型无效 / Invalid file type'),
    query('search')
      .optional()
      .isLength({ max: 200 })
      .withMessage('搜索关键词不能超过200字符 / Search keyword cannot exceed 200 characters'),
    query('includeDeleted')
      .optional()
      .isBoolean()
      .withMessage('包含已删除必须是布尔值 / Include deleted must be boolean')
  ],
  async (req, res, next) => {
    try {
      // 验证输入
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '输入验证失败 / Input validation failed',
          errors: errors.array()
        });
      }

      const { id: userId } = req.user;
      const {
        page = 1,
        pageSize = 20,
        folderPath = '/',
        fileType = null,
        search = '',
        includeDeleted = false
      } = req.query;

      let result;

      if (search) {
        // 搜索文件
        result = await File.searchFiles(userId, search, {
          page: parseInt(page),
          pageSize: parseInt(pageSize),
          fileType
        });
      } else {
        // 获取文件列表
        result = await File.getUserFiles(userId, {
          page: parseInt(page),
          pageSize: parseInt(pageSize),
          folderPath,
          fileType,
          includeDeleted: includeDeleted === 'true'
        });
      }

      res.json({
        success: true,
        message: '获取文件列表成功 / Get files list successful',
        ...result
      });

    } catch (error) {
      logger.error('获取文件列表失败 / Failed to get files list', {
        userId: req.user?.id,
        error: error.message
      });
      next(error);
    }
  }
);

/**
 * 获取单个文件信息
 * GET /api/files/:id
 */
router.get('/:id', async (req, res, next) => {
  try {
    const { id: fileId } = req.params;
    const { id: userId } = req.user;

    // 验证文件ID
    if (!fileId || isNaN(fileId)) {
      return res.status(400).json({
        success: false,
        message: '无效的文件ID / Invalid file ID'
      });
    }

    const file = await File.getFileDetail(parseInt(fileId), userId);

    if (!file) {
      return res.status(404).json({
        success: false,
        message: '文件不存在 / File not found'
      });
    }

    res.json({
      success: true,
      message: '获取文件信息成功 / Get file info successful',
      file
    });

  } catch (error) {
    logger.error('获取文件信息失败 / Failed to get file info', {
      userId: req.user?.id,
      fileId: req.params.id,
      error: error.message
    });
    next(error);
  }
});

/**
 * 文件上传
 * POST /api/files/upload
 */
router.post('/upload', async (req, res, next) => {
  try {
    const { id: userId } = req.user;
    const upload = fileUploadService.configureMulter();

    // 使用multer中间件处理文件上传
    upload.array('files', 10)(req, res, async (err) => {
      if (err) {
        logger.error('文件上传中间件错误 / File upload middleware error', {
          userId,
          error: err.message
        });

        if (err.code === 'LIMIT_FILE_SIZE') {
          return res.status(413).json({
            success: false,
            message: '文件大小超出限制 / File size exceeds limit'
          });
        }

        if (err.code === 'LIMIT_FILE_COUNT') {
          return res.status(400).json({
            success: false,
            message: '文件数量超出限制 / File count exceeds limit'
          });
        }

        return res.status(400).json({
          success: false,
          message: err.message || '文件上传失败 / File upload failed'
        });
      }

      if (!req.files || req.files.length === 0) {
        return res.status(400).json({
          success: false,
          message: '没有选择文件 / No files selected'
        });
      }

      // 创建上传任务并获取uploadId
      const uploadId = fileUploadService.createUploadTask(userId, req.files);
      
      // 立即返回uploadId，让客户端可以跟踪进度
      res.status(202).json({
        success: true,
        message: '文件上传已开始 / File upload started',
        uploadId,
        totalFiles: req.files.length
      });

      // 异步处理文件上传
      setImmediate(async () => {
        const uploadResults = [];
        const errors = [];

        // 处理每个上传的文件
        for (let i = 0; i < req.files.length; i++) {
          const file = req.files[i];
          
          try {
            // 更新进度：开始处理文件
            fileUploadService.updateUploadProgress(uploadId, i, 0, 'uploading');

            // 处理上传后的文件
            const processedFile = await fileUploadService.processUploadedFile(file, userId);

            // 更新进度：文件处理完成50%
            fileUploadService.updateUploadProgress(uploadId, i, 50, 'uploading');

            // 保存文件信息到数据库
            const fileRecord = await File.createFile(userId, {
              filename: processedFile.filename,
              original_name: processedFile.originalName,
              file_path: processedFile.filePath,
              file_size: processedFile.fileSize,
              mime_type: processedFile.mimeType,
              file_type: processedFile.fileType,
              folder_path: req.body.folderPath || '/',
              thumbnail_path: processedFile.thumbnailPath
            });

            uploadResults.push(fileRecord);

            // 更新进度：文件完成
            fileUploadService.updateUploadProgress(uploadId, i, 100, 'completed');

            logger.info('文件上传成功 / File uploaded successfully', {
              userId,
              uploadId,
              fileId: fileRecord.id,
              filename: fileRecord.filename,
              fileSize: fileRecord.file_size
            });

          } catch (fileError) {
            logger.error('处理单个文件失败 / Failed to process individual file', {
              userId,
              uploadId,
              filename: file.originalname,
              error: fileError.message
            });

            // 更新进度：文件失败
            fileUploadService.updateUploadProgress(uploadId, i, 0, 'failed', fileError.message);

            errors.push({
              filename: file.originalname,
              error: fileError.message
            });
          }
        }

        logger.info('文件上传批次完成 / File upload batch completed', {
          userId,
          uploadId,
          totalUploaded: uploadResults.length,
          totalFailed: errors.length
        });
      });

    });

  } catch (error) {
    logger.error('文件上传失败 / File upload failed', {
      userId: req.user?.id,
      error: error.message
    });
    next(error);
  }
});

/**
 * 更新文件信息
 * PUT /api/files/:id
 */
router.put('/:id',
  [
    body('original_name')
      .optional()
      .isLength({ min: 1, max: 255 })
      .withMessage('文件名长度必须在1-255字符之间 / Filename length must be between 1-255 characters'),
    body('folder_path')
      .optional()
      .isLength({ max: 500 })
      .withMessage('文件夹路径不能超过500字符 / Folder path cannot exceed 500 characters'),
    body('is_public')
      .optional()
      .isBoolean()
      .withMessage('公开状态必须是布尔值 / Public status must be boolean')
  ],
  async (req, res, next) => {
    try {
      // 验证输入
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '输入验证失败 / Input validation failed',
          errors: errors.array()
        });
      }

      const { id: fileId } = req.params;
      const { id: userId } = req.user;

      // 验证文件ID
      if (!fileId || isNaN(fileId)) {
        return res.status(400).json({
          success: false,
          message: '无效的文件ID / Invalid file ID'
        });
      }

      const updateData = {};
      const { original_name, folder_path, is_public } = req.body;

      // 只更新提供的字段
      if (original_name !== undefined) updateData.original_name = original_name;
      if (folder_path !== undefined) updateData.folder_path = folder_path;
      if (is_public !== undefined) updateData.is_public = is_public;

      if (Object.keys(updateData).length === 0) {
        return res.status(400).json({
          success: false,
          message: '没有提供要更新的数据 / No data provided for update'
        });
      }

      const updatedFile = await File.updateFile(parseInt(fileId), userId, updateData);

      if (!updatedFile) {
        return res.status(404).json({
          success: false,
          message: '文件不存在或无权限 / File not found or no permission'
        });
      }

      res.json({
        success: true,
        message: '文件信息更新成功 / File info updated successfully',
        file: updatedFile
      });

    } catch (error) {
      logger.error('更新文件信息失败 / Failed to update file info', {
        userId: req.user?.id,
        fileId: req.params.id,
        error: error.message
      });
      next(error);
    }
  }
);

/**
 * 获取上传进度
 * GET /api/files/upload/progress/:uploadId
 */
router.get('/upload/progress/:uploadId', async (req, res, next) => {
  try {
    const { uploadId } = req.params;
    const { id: userId } = req.user;

    if (!uploadId) {
      return res.status(400).json({
        success: false,
        message: '无效的上传ID / Invalid upload ID'
      });
    }

    const progress = await fileUploadService.getUploadProgress(uploadId, userId);

    if (!progress) {
      return res.status(404).json({
        success: false,
        message: '上传进度不存在 / Upload progress not found'
      });
    }

    res.json({
      success: true,
      progress
    });

  } catch (error) {
    logger.error('获取上传进度失败 / Failed to get upload progress', {
      userId: req.user?.id,
      uploadId: req.params.uploadId,
      error: error.message
    });
    next(error);
  }
});

/**
 * 取消文件上传
 * DELETE /api/files/upload/:uploadId
 */
router.delete('/upload/:uploadId', async (req, res, next) => {
  try {
    const { uploadId } = req.params;
    const { id: userId } = req.user;

    if (!uploadId) {
      return res.status(400).json({
        success: false,
        message: '无效的上传ID / Invalid upload ID'
      });
    }

    const cancelled = await fileUploadService.cancelUpload(uploadId, userId);

    if (!cancelled) {
      return res.status(404).json({
        success: false,
        message: '上传任务不存在或已完成 / Upload task not found or already completed'
      });
    }

    res.json({
      success: true,
      message: '上传已取消 / Upload cancelled'
    });

  } catch (error) {
    logger.error('取消上传失败 / Failed to cancel upload', {
      userId: req.user?.id,
      uploadId: req.params.uploadId,
      error: error.message
    });
    next(error);
  }
});

/**
 * 创建文件夹
 * POST /api/files/folder
 */
router.post('/folder',
  [
    body('folderPath')
      .notEmpty()
      .withMessage('文件夹路径不能为空 / Folder path cannot be empty')
      .isLength({ max: 500 })
      .withMessage('文件夹路径不能超过500字符 / Folder path cannot exceed 500 characters'),
    body('folderName')
      .notEmpty()
      .withMessage('文件夹名称不能为空 / Folder name cannot be empty')
      .isLength({ min: 1, max: 100 })
      .withMessage('文件夹名称长度必须在1-100字符之间 / Folder name length must be between 1-100 characters')
      .matches(/^[^<>:"/\\|?*]+$/)
      .withMessage('文件夹名称包含非法字符 / Folder name contains illegal characters')
  ],
  async (req, res, next) => {
    try {
      // 验证输入
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '输入验证失败 / Input validation failed',
          errors: errors.array()
        });
      }

      const { id: userId } = req.user;
      const { folderPath, folderName } = req.body;

      // 构建完整的文件夹路径
      const fullFolderPath = path.posix.join(folderPath, folderName);

      // 检查文件夹是否已存在
      const existingFiles = await File.getUserFiles(userId, {
        folderPath: fullFolderPath,
        pageSize: 1
      });

      if (existingFiles.data.length > 0) {
        return res.status(409).json({
          success: false,
          message: '文件夹已存在 / Folder already exists'
        });
      }

      // 创建物理文件夹
      const userPath = path.join(fileUploadService.uploadPath, userId.toString());
      const physicalFolderPath = path.join(userPath, fullFolderPath.substring(1)); // 去掉开头的 /
      
      await fs.mkdir(physicalFolderPath, { recursive: true });

      res.json({
        success: true,
        message: '文件夹创建成功 / Folder created successfully',
        folderPath: fullFolderPath
      });

    } catch (error) {
      logger.error('创建文件夹失败 / Failed to create folder', {
        userId: req.user?.id,
        folderPath: req.body.folderPath,
        folderName: req.body.folderName,
        error: error.message
      });
      next(error);
    }
  }
);

/**
 * 获取文件夹列表
 * GET /api/files/folders
 */
router.get('/folders',
  [
    query('parentPath')
      .optional()
      .isLength({ max: 500 })
      .withMessage('父路径不能超过500字符 / Parent path cannot exceed 500 characters')
  ],
  async (req, res, next) => {
    try {
      // 验证输入
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '输入验证失败 / Input validation failed',
          errors: errors.array()
        });
      }

      const { id: userId } = req.user;
      const { parentPath = '/' } = req.query;

      const folders = await File.getFolders(userId, parentPath);

      res.json({
        success: true,
        message: '获取文件夹列表成功 / Get folders list successful',
        folders,
        parentPath
      });

    } catch (error) {
      logger.error('获取文件夹列表失败 / Failed to get folders list', {
        userId: req.user?.id,
        parentPath: req.query.parentPath,
        error: error.message
      });
      next(error);
    }
  }
);

/**
 * 移动文件
 * PUT /api/files/:id/move
 */
router.put('/:id/move',
  [
    body('newFolderPath')
      .notEmpty()
      .withMessage('新文件夹路径不能为空 / New folder path cannot be empty')
      .isLength({ max: 500 })
      .withMessage('文件夹路径不能超过500字符 / Folder path cannot exceed 500 characters')
  ],
  async (req, res, next) => {
    try {
      // 验证输入
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '输入验证失败 / Input validation failed',
          errors: errors.array()
        });
      }

      const { id: fileId } = req.params;
      const { id: userId } = req.user;
      const { newFolderPath } = req.body;

      // 验证文件ID
      if (!fileId || isNaN(fileId)) {
        return res.status(400).json({
          success: false,
          message: '无效的文件ID / Invalid file ID'
        });
      }

      const moved = await File.moveFile(parseInt(fileId), userId, newFolderPath);

      if (!moved) {
        return res.status(404).json({
          success: false,
          message: '文件不存在或无权限 / File not found or no permission'
        });
      }

      res.json({
        success: true,
        message: '文件移动成功 / File moved successfully'
      });

    } catch (error) {
      logger.error('移动文件失败 / Failed to move file', {
        userId: req.user?.id,
        fileId: req.params.id,
        newFolderPath: req.body.newFolderPath,
        error: error.message
      });
      next(error);
    }
  }
);

/**
 * 获取用户存储统计
 * GET /api/files/storage/stats
 */
router.get('/storage/stats', async (req, res, next) => {
  try {
    const { id: userId } = req.user;

    // 获取文件统计
    const fileStats = await File.getUserFileStats(userId);
    
    // 获取用户存储信息
    const User = require('../database/models/User');
    const storageStats = await User.getStorageStats(userId);

    res.json({
      success: true,
      message: '获取存储统计成功 / Get storage stats successful',
      stats: {
        ...fileStats,
        ...storageStats,
        usagePercentage: storageStats.limit > 0 
          ? Math.round((storageStats.used / storageStats.limit) * 100) 
          : 0
      }
    });

  } catch (error) {
    logger.error('获取存储统计失败 / Failed to get storage stats', {
      userId: req.user?.id,
      error: error.message
    });
    next(error);
  }
});

/**
 * 文件下载/预览
 * GET /api/files/:id/download
 */
router.get('/:id/download',
  [
    query('preview')
      .optional()
      .isBoolean()
      .withMessage('预览参数必须是布尔值 / Preview parameter must be boolean')
  ],
  async (req, res, next) => {
    try {
      const { id: fileId } = req.params;
      const { id: userId } = req.user;
      const { preview = false } = req.query;

      // 验证文件ID
      if (!fileId || isNaN(fileId)) {
        return res.status(400).json({
          success: false,
          message: '无效的文件ID / Invalid file ID'
        });
      }

      const file = await File.getFileDetail(parseInt(fileId), userId);

      if (!file) {
        return res.status(404).json({
          success: false,
          message: '文件不存在 / File not found'
        });
      }

      // 检查文件是否存在于磁盘
      try {
        await fs.access(file.file_path);
      } catch (error) {
        return res.status(404).json({
          success: false,
          message: '文件不存在于磁盘 / File not found on disk'
        });
      }

      // 增加下载次数（仅非预览模式）
      if (!preview) {
        await File.incrementDownloadCount(parseInt(fileId));
      }

      // 设置响应头
      res.setHeader('Content-Type', file.mime_type);
      res.setHeader('Content-Length', file.file_size);

      if (preview === 'true') {
        // 预览模式：在浏览器中显示
        res.setHeader('Content-Disposition', `inline; filename="${encodeURIComponent(file.original_name)}"`);
      } else {
        // 下载模式：强制下载
        res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(file.original_name)}"`);
      }

      // 发送文件
      const fileStream = require('fs').createReadStream(file.file_path);
      fileStream.pipe(res);

      fileStream.on('error', (error) => {
        logger.error('文件流读取错误 / File stream read error', {
          fileId,
          userId,
          error: error.message
        });
        if (!res.headersSent) {
          res.status(500).json({
            success: false,
            message: '文件读取失败 / Failed to read file'
          });
        }
      });

    } catch (error) {
      logger.error('文件下载失败 / Failed to download file', {
        userId: req.user?.id,
        fileId: req.params.id,
        error: error.message
      });
      next(error);
    }
  }
);

/**
 * 获取文件缩略图
 * GET /api/files/:id/thumbnail
 */
router.get('/:id/thumbnail', async (req, res, next) => {
  try {
    const { id: fileId } = req.params;
    const { id: userId } = req.user;

    // 验证文件ID
    if (!fileId || isNaN(fileId)) {
      return res.status(400).json({
        success: false,
        message: '无效的文件ID / Invalid file ID'
      });
    }

    const file = await File.getFileDetail(parseInt(fileId), userId);

    if (!file) {
      return res.status(404).json({
        success: false,
        message: '文件不存在 / File not found'
      });
    }

    if (!file.thumbnail_path) {
      return res.status(404).json({
        success: false,
        message: '缩略图不存在 / Thumbnail not found'
      });
    }

    // 检查缩略图文件是否存在
    try {
      await fs.access(file.thumbnail_path);
    } catch (error) {
      return res.status(404).json({
        success: false,
        message: '缩略图文件不存在 / Thumbnail file not found'
      });
    }

    // 设置响应头
    res.setHeader('Content-Type', 'image/webp');
    res.setHeader('Cache-Control', 'public, max-age=86400'); // 缓存1天

    // 发送缩略图文件
    const thumbnailStream = require('fs').createReadStream(file.thumbnail_path);
    thumbnailStream.pipe(res);

    thumbnailStream.on('error', (error) => {
      logger.error('缩略图流读取错误 / Thumbnail stream read error', {
        fileId,
        userId,
        error: error.message
      });
      if (!res.headersSent) {
        res.status(500).json({
          success: false,
          message: '缩略图读取失败 / Failed to read thumbnail'
        });
      }
    });

  } catch (error) {
    logger.error('获取缩略图失败 / Failed to get thumbnail', {
      userId: req.user?.id,
      fileId: req.params.id,
      error: error.message
    });
    next(error);
  }
});

/**
 * 删除文件（软删除）
 * DELETE /api/files/:id
 */
router.delete('/:id', async (req, res, next) => {
  try {
    const { id: fileId } = req.params;
    const { id: userId } = req.user;

    // 验证文件ID
    if (!fileId || isNaN(fileId)) {
      return res.status(400).json({
        success: false,
        message: '无效的文件ID / Invalid file ID'
      });
    }

    const deletedFile = await File.deleteFile(parseInt(fileId), userId);

    if (!deletedFile) {
      return res.status(404).json({
        success: false,
        message: '文件不存在或无权限 / File not found or no permission'
      });
    }

    // 更新用户存储使用量
    await fileUploadService.updateUserStorage(userId);

    res.json({
      success: true,
      message: '文件删除成功 / File deleted successfully'
    });

  } catch (error) {
    logger.error('删除文件失败 / Failed to delete file', {
      userId: req.user?.id,
      fileId: req.params.id,
      error: error.message
    });
    next(error);
  }
});
module.
exports = router;